package com.hsy.crm.web.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.hsy.crm.web.domain.cm.App;
import com.hsy.crm.web.domain.cm.PageResult;
import com.hsy.crm.web.domain.cm.Unified;
import com.hsy.crm.web.domain.entity.Menu;
import com.hsy.crm.web.domain.entity.User;
import com.hsy.crm.web.domain.entity.UserRole;
import com.hsy.crm.web.domain.ex.ServiceException;
import com.hsy.crm.web.domain.po.user.UserPagePo;
import com.hsy.crm.web.domain.vo.user.UserAuthorityVo;
import com.hsy.crm.web.domain.vo.user.UserPageVo;
import com.hsy.crm.web.mapper.UserMapper;
import com.hsy.crm.web.mapper.UserRoleMapper;
import com.hsy.crm.web.service.base.BaseService;
import com.hsy.crm.web.service.base.CacheService;
import com.hsy.crm.web.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
public class UserService extends BaseService<User> {

    @Autowired
    UserMapper userMapper;

    @Autowired
    UserRoleMapper userRoleMapper;

    public Unified<List<User>> selectUser(User user) {
        Unified<List<User>> unified = new Unified<>();
        unified.setData(userMapper.selectAllUsers(user));
        return unified;
    }

    public User selectForLogin(User user){
        return userMapper.selectForLogin(user);
    }

    @Transactional
    public Unified<Integer> insertUser(User user) {
        Unified<Integer> unified = new Unified<>();

        User checkUser = new User();
        checkUser.setCustomerId(user.getCustomerId());
        checkUser.setUsername(user.getUsername());
        int users = userMapper.selectCount(checkUser);
        if( users > 0 ){
            unified.setResult(App.BussError.USER_NAME.getCode());
            return unified;
        }

        if( !StringUtils.isEmpty(user.getPhone()) ){
            checkUser = new User();
            checkUser.setCustomerId(user.getCustomerId());
            checkUser.setPhone(user.getPhone());
            users = userMapper.selectCount(checkUser);
            if( users > 0 ){
                unified.setResult(App.BussError.USER_PHONE.getCode());
                return unified;
            }
        }

        user.setPassword(Md5Utils.encrypt(user.getPassword()));
        user.setCreateTime(DateUtils.millis());
        user.setCreateUserId(user.getLoginUserId());
        user.setId(UuidUtils.getUuid());
        userMapper.inserts(user);
        return unified;
    }
    @Transactional
    public Unified<Integer> deleteUser(User user) {

        if( user.getId().equals(user.getLoginUserId()) ){
            throw new ServiceException(App.BussError.USER_DEELTE.getCode());
        }

       return Unified.newInstance(this.delete(user));
    }

    public PageResult<UserPagePo> page(UserPageVo userPageVo) {
        Page page = PageHelper.startPage(userPageVo.getPage(),userPageVo.getLimit());
        PageResult<UserPagePo> pageResult = new PageResult<>();

        if(userPageVo.getCompanyId()==null){
            userPageVo.setCompanyId(userPageVo.getLoginCompanyId());
        }

        pageResult.setRows(userMapper.page(userPageVo));
        pageResult.setTotal(page.getTotal());
        return pageResult;
    }

    public Unified<User> getUser(User user) {
        User dbUser = this.selectOne(user);
        dbUser.setPassword(null);
        dbUser.setCardNo(null);
        return Unified.newInstance(dbUser);
    }

    public Unified findMenus(User user) {

        List<Long> menuIds = userMapper.findUserMenuIds(user);
        Map<Long,Menu> wholeMenus = CacheService.getMenus();

        List<Menu> userMenus = Lists.newArrayList();
        for( Long menuId : menuIds ){
            userMenus.add(wholeMenus.get(menuId));
        }

        return Unified.newInstance(userMenus);

    }

    /*public Unified resetpass(User user) {
        Unified unified = new Unified();
        User updateUser = new User();
        updateUser.setId(user.getId());
        String pass = genRandomPass();
        updateUser.setPassword(Md5Utils.encrypt(pass));
        userMapper.updateByPrimaryKeySelective(updateUser);
        unified.setData(pass);
        return unified;
    }*/

    @Transactional
    public Unified authority(UserAuthorityVo vo) {
        Unified unified = new Unified();

        User user = new User();
        user.setCustomerId(vo.getCustomerId());
        user.setId(vo.getId());
        User dbUser = userMapper.selectByPrimaryKey(user);

        UserRole delete = new UserRole();
        delete.setCustomerId(vo.getCustomerId());
        delete.setUserId(vo.getId());
        delete.setCompanyId(dbUser.getCompanyId());
        userRoleMapper.delete(delete);

        List<UserRole> userRoles = vo.getUserRoles();
        for( UserRole userRole : userRoles ){
            userRole.setId(UuidUtils.getUuid());
            userRole.setCompanyId(dbUser.getCompanyId());
            userRole.setUserId(vo.getId());
            userRole.setCustomerId(vo.getCustomerId());
            userRoleMapper.insert(userRole);
        }

        return unified;
    }

    @Transactional
    public Unified<Integer> updateUser(User user) {

        //用户名不能修改
        user.setUsername(null);

        return Unified.newInstance(this.update(user));
    }

    private static String genRandomPass(){
        String pass = "";
        pass += getLowchar();

        for( int i=0 ; i<10 ; i++ ){

            int random = RandomUtils.nextInt(3);
            if( random == 0 ){
                pass += getNumber();
            }else if(random == 1){
                pass += getUpchar();
            }else if(random == 2){
                pass += getLowchar();
            }

        }


        return pass;
    }

    private static int getNumber(){
        return RandomUtils.nextInt(10);
    }

    private static char getUpchar(){
        return (char)('A'+RandomUtils.nextInt(26));
    }

    private static char getLowchar(){
        return (char)('a'+RandomUtils.nextInt(26));
    }

}
